from .base_webdriver import BaseWebDriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
import time
from cfg import *


class LoginUI(BaseWebDriver):       # 继承父类BaseWebDriver的所有属性和方法
    def __init__(self):
        super().__init__()          # 调用父类的初始化方法，确保浏览器实例化

    def login(self, username, password):
        """
        登录方法，自动清空输入框后填写用户名和密码
            username (str): 用户名
            password (str): 密码
        """
        # 导航到登录页面
        self.wd.get(SMP_URL_LOGIN)
        wait = self.wait
        wait.until(EC.element_to_be_clickable((By.ID, 'username')))

        # 填写用户名（等待可点击 → 清空 → 输入；失败兜底直接输入）
        if username is not None:  # 当传过来的username是None时会跳过输入。（传过来的数据为空时该数值已经被转换为None了）
            username_input = wait.until(EC.element_to_be_clickable((By.ID, 'username')))
            try:
                username_input.clear()
                username_input.send_keys(username)
            except Exception as e:
                print(f"用户名输入失败: {e}")
                # 如果清除失败，尝试直接输入，原因：某些输入框对 clear() 不友好但仍可输入，以下同理
                username_input.send_keys(username)

        # 填写密码（等待可点击 → 清空 → 输入；失败兜底直接输入）
        if password is not None:
            password_input = wait.until(EC.element_to_be_clickable((By.ID, 'password')))
            try:
                password_input.clear()  
                password_input.send_keys(password)
            except Exception as e:
                print(f"密码输入失败: {e}")
                password_input.send_keys(password)

        login_btn = wait.until(EC.element_to_be_clickable((By.ID, 'loginBtn')))
        login_btn.click()

        # 登录后等待页面进入目标态：nav 出现或错误 alert 出现（二选一）
        try:
            # 先判断 alert，再判断导航元素，避免在 alert 存在时调用 find_elements 引发异常
            wait.until(lambda d: EC.alert_is_present()(d) or d.find_elements(By.TAG_NAME, 'nav'))
        except TimeoutException:
            # 若二选一条件未达成，保持函数继续，后续测试会给出断言信息
            pass